import React from 'react'
import {Map, Marker, NavigationControl, InfoWindow, MapvLayer, PointLabel,Polyline} from 'react-bmap';
import {Button, Card, Col, DatePicker, Modal, Radio, message} from "antd";
import {FormattedMessage} from "../../utils/locale";
import styles from "./index.less";
import {STAY, TRAIL} from "../../config/const";
import {gcj02tobd09} from "../../utils/coordtransform";
import {computeColor, ts2time} from "../../utils/utils";
import moment from "moment";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import BMap from 'BMap';
import 'moment/locale/zh-cn';
import CustomMarker from "./CustomMarker";
import MarkerClusterer from "../../utils/MarkerClusterer";
import CustomClusterMarker from "./CustomClusterMarker";
import {createShareMapLink} from "../../services/map";


import device_2 from '../../assets/device_2.png'

moment.locale('zh-cn');
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;

const {RangePicker} = DatePicker;


class BasicMap extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      center: {lng: 136.402544, lat: 39.928216},
      zoom: 5,
      isFullScreen: false,
      isShowShareModal: false,
      isShareDone: false,
      confirmLoading: false,
      shareRsp: null,
      today:moment(),
      // selectDate: null,
    };
    this.Map = React.createRef();
    this.zoom = 5
  }
  componentDidMount() {
    var myIcon = new BMap.Icon(device_2, new BMap.Size(300,157));
    //设置marker图标为人字形
    var map=this.Map.current.map;//获取真实map
    var pt1 = new BMap.Point(119, 40);
    var mk1 = new BMap.Marker(pt1,{icon:myIcon});
    map.addOverlay(mk1);
    // console.log(this.Map.current.map);

  }

  static getDerivedStateFromProps(props, state) {
    const marks = props.marks;
    const length = marks.length;
    const newState = {};
    if (length > 0) {
      Object.assign(newState, {center: marks[length - 1].xy, zoom: 6});
    }
   // newState  最后一个经纬度信息
    return newState;
  }
  handleMarkerCluster(marks, points) {
    if (marks.length < 1) return [];
    const map = this.Map.current.map;
    const newMarkers = marks.map((item, idx) => {
      const pt = new BMap.Point(item.xy.lng, item.xy.lat);
      const mk = new BMap.Marker(pt);
      mk.info = points[idx];
      return mk;
    });
    const markerClusterer = new MarkerClusterer(map, {markers: newMarkers});
    return markerClusterer.getClusters();
  }
  componentWillUnmount() {
    if (this.bubbleContentDom) {
      this.bubbleContentDom.removeEventListener('click', this.bubbleContentHandler);
    }

  }
  marksEventsHandler = info => {
    const {infoWindowHandler} = this.props;
    return {
      click(e) {
        let point = null;
        if (e.target && e.target.point) {
          point = e.target.point
        } else {
          point = {lng: info.xy[0], lat: info.xy[1]}
        }
        infoWindowHandler(point, info);
      }
    }
  };
  infoWindowEventsHandler = _ => {
    const self = this;
    return {
      open(e) {
        if (!self.bubbleContentDom) {
          const bubbleContentDom
            = self.bubbleContentDom
            = document.querySelector('.BMap_bubble_content');
          bubbleContentDom.addEventListener('click', self.bubbleContentHandler);
        }
      }
    }
  };
  bubbleContentHandler = (e) => {
    const {handleChangeState} = this.props;
    const target = e.target;
    if (target && target.className) {
      const type = target.className;
      if ([STAY, TRAIL].includes(type)) {
        handleChangeState({type, datePickerVisible: true})
      }
    }
  };
  /**
   * 线上点的点击事件
   */
  handleTrailPointClick = (e) => {
    if (e && e.geometry) {
      const {handleChangeState, trailList} = this.props;
      const idx = e.count;
      let {lng, lat, device_id, battery_level, client_log_time, speed} = trailList[idx];
      [lng, lat] = gcj02tobd09(lng, lat);
      const xy = {lng, lat};
      // todo fix
      const text = `
         <dl>
          <dt>设备序列号:</dt>
            <dd>${device_id}</dd>
          <dt>电量:</dt>
            <dd>${battery_level} %</dd> 
          <dt>时间:</dt>
            <dd>${ts2time(client_log_time)}</dd>
          <dt>坐标:</dt>
            <dd>${lng}, ${lat}</dd>
        </dl>
      `;
      handleChangeState({infoWindowPosition: xy, infoWindowText: text, cur_device: device_id})
    }
  };

  handlerTrailData = (trails) => {
    const ptData = [];
    const plData = [];
    // let lastSpeed = 0;
    let lastXy = null;
    trails.forEach((item, idx) => {
      if (!item) return;
      // const speed = item.speed / 1e3;
      const xy = gcj02tobd09(item.lng, item.lat);
      const pt = {
        "geometry": {
          "type": "Point",
          "coordinates": xy
        },
        // "fillStyle": computeColor(speed),
        "fillStyle": 'red',
        "count": idx,
      };
      ptData.push(pt);
      if (idx > 0) {
        const pl = {
          "geometry": {
            "type": 'LineString',
            "coordinates": [
              lastXy, xy
            ]
          },
          // "strokeStyle": computeColor((lastSpeed + speed) / 2),
          "strokeStyle": 'green',
          "count": idx,
        };
        plData.push(pl);
      }
      // lastSpeed = speed;
      lastXy = xy;
    });
    const startPt = ptData[0];
    const endPt = ptData[ptData.length - 1];
    let startXY = {};
    let endXY = {};
    if (startPt) {
      startXY = {lng: startPt.geometry.coordinates[0], lat: startPt.geometry.coordinates[1]};
      endXY = {lng: endPt.geometry.coordinates[0], lat: endPt.geometry.coordinates[1]}
    }
    return [ptData, plData, startXY, endXY];
  };

  handleRequestFullScreen = () => {
    const {isFullScreen} = this.state;
    const element = document.documentElement;
    if (isFullScreen) {
      if (document.exitFullscreen) {
        document.exitFullscreen();
      } else if (document.mozCancelFullScreen) {
        document.mozCancelFullScreen();
      } else if (document.webkitExitFullscreen) {
        document.webkitExitFullscreen();
      }
      this.setState({isFullScreen: false})
    } else {
      if (element.requestFullscreen) {
        element.requestFullscreen();
      } else if (element.mozRequestFullScreen) {
        element.mozRequestFullScreen();
      } else if (element.webkitRequestFullscreen) {
        element.webkitRequestFullscreen();
      } else if (element.msRequestFullscreen) {
        element.msRequestFullscreen();
      }
      this.setState({isFullScreen: true})
    }
  };

  handleRangePickerChange = (dates) => {

    this.props.handleChangeState({selectDate: dates})
  };

  handleWheelAction = () => {
    this.zoom = this.Map.current && this.Map.current.map.getZoom();
    this.props.handleChangeState({
      infoWindowPosition: null,
      infoWindowText: '',
    })
    // this.forceUpdate()
  };

  handleClickShareMap = () => {
    this.setState({isShowShareModal: true})
  };

  handleCreateShareMapLink = async () => {
    const {cur_device, start_time, end_time,} = this.props;
    const {isShareDone} = this.state;
    if (!isShareDone) {
      this.setState({confirmLoading: true});
      const hours = this._hours || 6;
      try {
        const rsp = await createShareMapLink({device_id: cur_device, start_time, end_time, hours});

        if (rsp.statusCode === 201) {
          this.setState({confirmLoading: false, isShareDone: true, shareRsp: rsp})
        }
      } catch (e) {
        this.setState({confirmLoading: false, isShareDone: true,})
      }
    } else {
      this.handleCancel()
    }
  };

  getShareModalContent = (rsp, isShareDone) => {
    if (!rsp) {
      if (!isShareDone) {
        return (
          <div>
            <h3>分享有效时长：</h3>
            <RadioGroup defaultValue="6" onChange={(e) => {
              this._hours = e.target.value
            }}>
              <RadioButton value="6">6小时</RadioButton>
              <RadioButton value="24">24小时</RadioButton>
              <RadioButton value="72">三天内</RadioButton>
              <RadioButton value="168">七天内</RadioButton>
            </RadioGroup>
          </div>
        )
      } else {
        return <p>
          创建分享链接失败, 请重新选择创建！
        </p>
      }
    }
    const _url = `${window.location.origin}/${rsp.data.key}/`;
    return <div>
      <p>链接地址： <input readOnly className={styles.urlInput} ref={input => this.$input = input} type="text" value={_url}/>
        <Button onClick={this.handleClickCopy}>复制</Button>
      </p>
    </div>
  };

  handleClickCopy = () => {
    this.$input.select();
    if (document.execCommand('copy')) {
      message.success('复制成功！')
    } else {
      message.error('复制失败，请手动复制！')
    }
  };

  handleCancel = () => {
    this.setState({isShowShareModal: false,}, () => (this.setState({
      shareRsp: null,
      confirmLoading: false,
      isShareDone: false
    })))
  };


   getDate=(date, dateString) =>{
      // console.log(date, dateString);
      this.setState({
        today:date
      })
   };
  
   prevDay=()=>{
     this.setState({
       today:this.state.today.add(-1,'days'),

     });
   };
   nextDay=()=>{
     this.setState({
       today:this.state.today.add(1,'days'),
     });
   };
  render() {
    const {
      marks, points, infoWindowPosition, infoWindowText, trailList, getDefaultDate, onOk, onDeviceListVisible,
      getLatestStaysList, deviceListVisible, cur_device, selectDate, deviceStatusMap, isTrail, handleChangeState
    } = this.props;
    const {center, zoom, isFullScreen, isShowShareModal, shareRsp, isShareDone, confirmLoading,} = this.state;
    const {marksEventsHandler} = this;

    const [ptData, plData, startXY, endXY] = isTrail ? this.handlerTrailData(trailList) : [[], [], {}, {}];

    // todo fix
    const clusters = !isTrail && this.handleMarkerCluster(marks, points);
    console.log(clusters)
    const ptOptions = {
      // shadowColor: 'rgba(255, 50, 50, 1)',
      shadowBlur: 0,
      // globalCompositeOperation: 'lighter',
      methods: {
        click: this.handleTrailPointClick,
      },
      size: 4,
      draw: 'simple'
    };
    const plOptions = {
      // shadowColor: 'rgba(255, 50, 50, 1)',
      shadowBlur: 0,
      // globalCompositeOperation: 'lighter',
      lineWidth: 1.8,
      draw: 'simple',
    };
    const defaultValue = getDefaultDate();


    function getClusterMarkers(clusters) {
      return clusters.map((cluster, idx) => {
            const len = cluster._markers.length;
            if (len === 1) {
              const info = cluster._markers[0].info;
              return (<CustomMarker status={deviceStatusMap[info.deviceid]} key={idx}
                                    events={marksEventsHandler(info)}
                                    position={cluster._center}/>
              )
            }
            const deviceList = [];
            const clusterInfo = cluster._markers.map((mk, idx) => {
              const deviceId = mk.info.deviceid;
              deviceList.push('' + deviceId);
              return React.createElement('p', {key: idx}, `${deviceId}`)
            });

            return (<CustomClusterMarker key={idx} events={{
                  click() {
                    handleChangeState({checkedKeys: deviceList,})
                  }
                }}
                                         clusterInfo={React.createElement('div', null, clusterInfo)}
                                         index={cluster._markers.length}
                                         position={cluster._center}/>
            )
          }
      )
    }

    return (
      <Card
        bodyStyle={{padding: '0'}}
        title={!!isTrail ?
          <React.Fragment>
            <Button type="primary" onClick={getLatestStaysList}>当前设备: {cur_device}</Button>
            <Button onClick={this.handleClickShareMap}>创建分享链接</Button>
          </React.Fragment> : '地图'}
        bordered={false}
        extra={
          <div className={styles.salesExtraWrap} style={{textAlign: "center",}}>
            <Button onClick={onDeviceListVisible}>{deviceListVisible ? '关闭' : '显示'}设备列表</Button>&nbsp;&nbsp;
            <Button type="primary" onClick={this.prevDay}>前一天</Button>
            <DatePicker  onChange={this.getDate} placeholder={'请选择日期'} local={locale} defaultValue={this.state.today} value={this.state.today}/>
            <Button type="primary" onClick={this.nextDay}>后一天</Button>
            {/*<RangePicker*/}
            {/*  locale={locale}*/}
            {/*  showTime={{format: 'HH:mm'}}*/}
            {/*  format="YYYY-MM-DD HH:mm"*/}
            {/*  placeholder={['Start Time', 'End Time']}*/}
            {/*  onChange={this.handleRangePickerChange}*/}
            {/*  defaultValue={defaultValue}*/}
            {/*  defaultPickerValue={defaultValue}*/}
            {/*  value={selectDate || defaultValue}*/}
            {/*  onOk={onOk}*/}
            {/*/>*/}
            &nbsp;&nbsp;
            <Button onClick={this.handleRequestFullScreen}>{isFullScreen ? '退出' : '进入'}全屏模式</Button>
          </div>
        }
      >
        <div className={styles.mapChart}>
          <Map ref={this.Map} center={infoWindowPosition || center} zoom={zoom}
               style={{height: 'calc(100vh - 250px)'}}
               events={{
                 zoomend: this.handleWheelAction,
                 dragend: this.handleWheelAction
               }}
               enableScrollWheelZoom={true}>

            {isTrail || this.zoom > 17 ?  marks.map((mark, idx) => <CustomMarker key={mark.key}
                                                              events={this.marksEventsHandler(points[idx])}
                                                              position={mark.xy}
                                                              index={idx + 1}
              >
              </CustomMarker>)
              : getClusterMarkers(clusters)
            }
            {infoWindowPosition && (
              <InfoWindow
                  position={infoWindowPosition}
                  events={this.infoWindowEventsHandler()}
                  text={infoWindowText}
                  width={300} height={0}/>
            )}
            {isTrail && (
              <Marker position={endXY} icon="end"/>
            )}
            {isTrail && (
              <Marker position={startXY} icon="start"/>
            )}
            {isTrail && (
              <MapvLayer data={ptData} options={ptOptions}/>
            )}
            {isTrail && (
              <MapvLayer data={plData} options={plOptions}/>
            )}
            <NavigationControl/>
            {/*{*/}
            {/*  <Marker position={{lng: this.state.mapJson[0].lng, lat: this.state.mapJson[0].lat}} icon='start'/>*/}
            {/*}*/}
            {/*{*/}
            {/*  <Marker position={{lng: this.state.mapJson[this.state.mapJson.length-1].lng, lat: this.state.mapJson[this.state.mapJson.length-1].lat}} icon='end'/>*/}
            {/*}*/}
            {/*<Polyline*/}
            {/*    strokeColor='green'*/}
            {/*    path={this.state.mapJson}*/}
            {/*/>*/}

          </Map>
        </div>
        {cur_device && <Modal
          title="创建分享链接"
          visible={isShowShareModal}
          onOk={this.handleCreateShareMapLink}
          confirmLoading={confirmLoading}
          onCancel={this.handleCancel}
        >
          {this.getShareModalContent(shareRsp, isShareDone)}
        </Modal>}
      </Card>
    )
  }
}


export default BasicMap;
